<template>
  <div class="viewport" ref="viewport" @scroll="scrollFn">
    <div class="scroll-bar" ref="scrollBar"></div>
    <div
      class="scroll-list"
      :style="{ transform: `translate3d(0, ${offset}px, 0)` }"
    >
      <div v-for="(item, index) in visibleData" :vid="item.id" :key="index">
        <!-- 作用域插槽 -->
        <slot :item="item" :size="size"></slot>
      </div>
    </div>
  </div>
</template>

<script>
import throttle from 'lodash/throttle'
export default {
  name: 'virtual-list',
  components: {},
  props: {
    size: Number, // 当前每一项的高度
    remain: Number, // 可见多少个
    items: Array // item项
  },
  data() {
    return {
      start: 0,
      end: this.remain,
      offset: 0
    }
  },
  computed: {
    // 渲染3屏
    prevCount() {
      // 前面预留几个(不足8个，取前面剩下所有的)
      return Math.min(this.start, this.remain)
    },
    nextCount() {
      // 后面预留几个(不足8个，取后面剩下所有的)
      return Math.min(this.remain, this.items.length - this.end)
    },
    visibleData() {
      let start = this.start - this.prevCount
      let end = this.end + this.nextCount
      return this.items.slice(start, end)
    }
  },
  watch: {},
  created() {
    // 200内只执行一次 -> 节流操作
    this.scrollFn = throttle(this.handleScroll, 200, { leading: false }) // 第一不触发
  },
  mounted() {
    this.$refs.viewport.style.height = this.size * this.remain + 'px'
    this.$refs.scrollBar.style.height = this.items.length * this.size + 'px' // 滚动条的高度
  },
  activated() {},
  deactivated() {},
  updated() {},
  beforeDestroy() {},
  destroyed() {},
  methods: {
    handleScroll() {
      console.log('handleScroll')
      //1.应该先 算出来当前滚过去几个了 ，当前应该从第几个开始显示
      let scrollTop = this.$refs.viewport.scrollTop
      // 获取当前应该从第几个开始渲染 -> 向下取整
      this.start = Math.floor(scrollTop / this.size) // 假设滚动了130， 40 ，3.25

      this.end = this.start + this.remain // 当前可渲染的区域

      this.offset = this.start * this.size - this.size * this.prevCount // 计算偏移量
    }
  },
  filters: {}
}
</script>
<style scoped lang="scss">
.viewport {
  overflow-y: scroll;
  position: relative;

  .scroll-list {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
  }
}
</style>
